import { computed, reactive, watch, ref } from 'vue'
import { type Options, RowSelection } from './type';
import Menus from './menus'

export default class extends Menus {
    constructor(options: Options){
        super(options)
        
        // 监控最后一行数据变化
        watch(() => this.dataSource.value.at(-1), (row: any = {}) => {
            if(this.props.keepLastRowEmpty ){
                const key = row[this.props.rowKey]
                this.lastRowKey.value = [key]
            } else {
                this.lastRowKey.value = []
            }
        }, {
            immediate: true,
            deep: true
        })
        
        // 监控数据长度变化
        watch(() => this.dataSource.value.length, () => {
            // 剔除不存在的key
            this.rowSelectionState.selectedRowKeys = this.rowSelectionState.selectedRowKeys.filter(key => {
                return this.dataSource.value.find((row: any) => row[this.props.rowKey] === key)
            })
        },{
            immediate: true
        })

        // 监控选择key变化
        watch(() => this.rowSelectionState.selectedRowKeys, () => {
            if(this.props.rowSelection?.onChange){
                this.props.rowSelection?.onChange(this.rowSelectionState.selectedRowKeys,  this.selectedRows.value)
            }
        }, {deep: true})

        // 同步外部变化
        if(this.props.rowSelection){
            watch(() => this.props.rowSelection?.selectedRowKeys, (val) => {
                this.rowSelectionState.selectedRowKeys = val
            }, { deep: true })
        }

        // 监控点选、框选状态，同步选择行
        watch(() => this.selectedState, () => {
            if (!this.props.relateRowChosed) return;

            if (!this.selectedState.rows && this.selectedState.startX !== -1) {
                this.rowSelectionState.selectedRowKeys = []
                return;
            };

            const {startY, endY, rows } = this.selectedState;
            let indexs: number[] = []

            if (rows){
                indexs = rows
            }
            if (startY !== undefined && endY !== undefined){
                let startY = this.getMinStartY()
                const endY = this.getMaxEndY()
                while(startY <= endY){
                    indexs.push(startY)
                    startY++;
                }
            }
            // 获取到点选、框选的key， 并过滤掉禁选的key
            const keys = indexs?.map((rowindex: number) => {
                return this.dataSource.value[rowindex][this.props.rowKey]
            }) //.filter(key => !this.disabeldCheckedRowKeys.value.includes(key))
            
            //if(!keys || JSON.stringify(keys) === JSON.stringify(this.rowSelectionState.selectedRowKeys)) return 

            this.rowSelectionState.selectedRowKeys = keys || [];
        }, {
            deep: true, 
            immediate: true
        })
        
    }

    // 最后空行的keys
    private lastRowKey = ref<string[]>([])
    /**
     * 行选择状态
     *
     */
    rowSelectionState = reactive<RowSelection>({
        selectedRowKeys: []
    }) 
    // 禁止选择的keys 
    disabeldCheckedRowKeys = computed(() => {
        return this.lastRowKey.value.concat(this.props.rowSelection?.disableSelectedRowKeys ?? [], this.props.disabled ?? [])
    })
    // 行是否被选中
    rowIsSelection (row: any){
        return this.rowSelectionState.selectedRowKeys.includes(row[this.props.rowKey])
    }
    // 是否全选（不包含禁止选择的）
    rowsCheckAll = computed(() => {
        const { selectedRowKeys } = this.rowSelectionState
        if (selectedRowKeys.length === 0) return false;
        return selectedRowKeys.length + (this.disabeldCheckedRowKeys.value.length ?? 0) >= this.dataSource.value.length
    })
    // 是否有选中的行
    rowsIndeterminate = computed(() => {
        return this.rowSelectionState.selectedRowKeys.length > 0 && !this.rowsCheckAll.value
    })
    // 选中行集合
    selectedRows = computed(() => {
        return this.dataSource.value.filter((row: any) => this.rowSelectionState.selectedRowKeys.includes(row[this.props.rowKey]))
    })
    /**
     * 全选 or 取消全选
     */
    selectAllRowHandel(){
        if(this.rowsCheckAll.value) this.rowSelectionState.selectedRowKeys = []
        else this.rowSelectionState.selectedRowKeys = this.dataSource.value.filter((v: any) => {
            const key = v[this.props.rowKey]
            // 跳过禁选
            if(this.disabeldCheckedRowKeys.value.includes(key)) return false
            return true
        }).map((v: any) => {
            return v[this.props.rowKey]
        })

        if(this.props.rowSelection?.onSelectAll){
            this.props.rowSelection?.onSelectAll(this.rowsCheckAll.value, this.rowSelectionState.selectedRowKeys,  this.selectedRows.value)
        }

        if (this.props.relateRowChosed) {

            this.selectedState.startY = this.selectedState.endY = undefined;
            this.selectedState.startX = this.selectedState.endX = undefined;
            this.selectedState.cells = this.selectedState.rows = undefined;
            this.selectedState.selectedTh = false

            if(this.rowsCheckAll.value) {
                this.selectedState.rows = []
                this.dataSource.value.forEach((row: any, rowindex: number) => {
                    if(!this.disabeldCheckedRowKeys.value.includes(row[this.props.rowKey])){
                        this.selectedState.rows?.push(rowindex)
                    }
                })
            }
        }
    }
    /**
     * 选择某行 or 取消选择某行
     * @param row 行数据
     * @param rowindex 行 index
     */
    selectRowHandel(row: any, rowindex: number){

        if(this.props.relateRowChosed) this.anyWhereSelectedRows(rowindex)

        const key = row[this.props.rowKey]
        if(this.rowSelectionState.selectedRowKeys.includes(key)) {
            this.rowSelectionState.selectedRowKeys = this.rowSelectionState.selectedRowKeys.filter(v => v !== key)
        }else{
            this.rowSelectionState.selectedRowKeys.push(key)
        }

        // 选中/取消选中回调
        if(this.props.rowSelection?.onSelect) {
            this.props.rowSelection?.onSelect(row, this.rowSelectionState.selectedRowKeys.includes(key), this.selectedRows.value)
        }
    }



    /**
     * 列选择状态
     *
     */
    colSelectionState = reactive({
        selectedColKeys: [],
        disableSelectedColKeys: []
    })
}